#include "scene.h"
#include "objmanager.h"
#include "entity.h"
#include "map.h"
#include "util.h"

Scene::Scene()
{
	mX = 0;
	mY = 0;
	mTop = 0;
	mLeft = 0;
	mWidth = 0;
	mHeight = 0;
	mMap = 0;
}

Scene::~Scene()
{

}

void Scene::Render( int layer )
{
	if( mMap )
	{
		if( layer == -1 )
			mMap->Render( mLeft, mTop, mX, mY );
		else
		{
			MapLayer *l = mMap->GetLayer( layer );
			if( l )
				l->Render( mLeft, mTop, mX, mY );
		}
	}
	for( EntityMap::iterator iter = mUpdateObjs.begin(); iter != mUpdateObjs.end(); iter++ )
	{
		Entity *e = iter->second;
		if( layer >= 0 && e->mLayer != layer )
			continue;
		int renderx = e->mX + mLeft - mX;
		int rendery = e->mY + mTop - mY;
		e->render(  renderx, rendery );
	}
}

Entity * Scene::GetEntity( int id )
{
	EntityMap::iterator iter = mObjs.find(id);
	if( iter != mObjs.end() )
	{
		return iter->second;
	}
	return 0;
}

void Scene::RemoveEntity( int id )
{
	EntityMap::iterator iter = mObjs.find( id );
	if( iter != mObjs.end() )
	{
		mObjs.erase( iter );
	}
}

void Scene::AddEntity( Entity *e )
{
	if( e==0 )
		return;
	mObjs[e->mID] = e;
}

void Scene::SaveEditor( std::ofstream &f )
{
	int size = mObjs.size();
	f.write((char *)&size,sizeof(int));
	for( EntityMap::iterator iter = mObjs.begin(); iter != mObjs.end(); iter++ )
	{
		Entity *e = iter->second;
		WriteString(f, e->mName);
		f.write((char *)&e->mX,sizeof(float));
		f.write((char *)&e->mY,sizeof(float));
		f.write((char *)&e->mLayer,sizeof(int));
	}
}

void Scene::LoadEditor( std::ifstream &f )
{
	extern gcn::Rectangle mapviewarea;
	mTop = mapviewarea.y;
	mLeft = mapviewarea.x;
	mWidth = mapviewarea.width;
	mHeight = mapviewarea.height;
	int size = 0;
	f.read((char *)&size,sizeof(int));
	while( size > 0 )
	{
		std::string objname;
		ReadString(f, objname);
		Entity *e = ObjManager::Instance().CreateObj( objname.c_str() );
		f.read((char *)&e->mX,sizeof(float));
		f.read((char *)&e->mY,sizeof(float));
		f.read((char *)&e->mLayer,sizeof(int));
		AddEntity( e );
		--size;
	}
}

void Scene::Update()
{
	mUpdateObjs.clear();
	gcn::Rectangle updatearea(mX - mWidth, mY - mHeight, 2*mWidth, 2*mHeight);
	for( EntityMap::iterator iter = mObjs.begin(); iter != mObjs.end(); iter++ )
	{
		Entity *e = iter->second;
		gcn::Rectangle boundbox = e->getBoundBox();
		if( updatearea.isIntersecting( boundbox ) )
		{
			mUpdateObjs[e->mID] = e;
		}
	}
}
